#include "StdAfx.h"
#include "Time.h"
#include <stdio.h>

//--------------------------------------------------------------------------------
TimeZone::Time::Time(void)
{
	memset(this, 0, sizeof(Time));
}
//--------------------------------------------------------------------------------
TimeZone::Time::Time(const SYSTEMTIME& time)
	: SYSTEMTIME(time)
{}
//--------------------------------------------------------------------------------
TimeZone::Time::Time(int utc)
{
	memset(this, 0, sizeof(Time));
	_time_tToSystemTime(utc, this);
}
//--------------------------------------------------------------------------------
TimeZone::Time::~Time(void)
{}
//----------------------------------------------------------------------------
bool TimeZone::Time::isValid(void) const
{
	return wYear > 0 && wMonth > 0 && wMonth <= 12 && wDay > 0 && wDay <= 31 && wHour <= 23 &&
		wMinute < 60 && wSecond < 60 && wMilliseconds < 1000; 
}
//----------------------------------------------------------------------------
void TimeZone::Time::print(void) const
{
	wprintf_s(L"%04d/%02d/%02d %02d:%02d:%02d:%03d", wYear, wMonth, wDay, wHour, wMinute, wSecond, wMilliseconds);
}
//----------------------------------------------------------------------------
int	TimeZone::Time::compare(const SYSTEMTIME& _right) const
{
	struct Mapping
	{
		unsigned short m_data[8];
	};

	const Mapping& _mthis  = reinterpret_cast<const Mapping&>(*this);
	const Mapping& _mright = reinterpret_cast<const Mapping&>(_right);

	for (int i = 0; i < 2; ++i)
	{
		if (_mthis.m_data[i] < _mright.m_data[i])
		{
			return -1;
		}
		if (_mthis.m_data[i] > _mright.m_data[i])
		{
			return 1;
		}
	}
	for (int i = 3; i < 8; ++i)
	{
		if (_mthis.m_data[i] < _mright.m_data[i])
		{
			return -1;
		}
		if (_mthis.m_data[i] > _mright.m_data[i])
		{
			return 1;
		}
	}
	return 0;
}
//----------------------------------------------------------------------------
bool TimeZone::Time::operator < (const SYSTEMTIME& _right) const
{
	return compare(_right) == -1;
}
//----------------------------------------------------------------------------
bool TimeZone::Time::operator <= (const SYSTEMTIME& _right) const
{
	return compare(_right) <= 0;
}
//----------------------------------------------------------------------------
bool TimeZone::Time::operator == (const SYSTEMTIME& _right) const
{
	return compare(_right) == 0;
}
//----------------------------------------------------------------------------
int TimeZone::Time::utc(int bias_sec) const
{
	FILETIME filetime;
	::SystemTimeToFileTime(this, &filetime);

	__int64 ll(filetime.dwHighDateTime);
	ll <<= 32;
	ll += filetime.dwLowDateTime;
	ll -= 0x19DB1DED53E8000;
	ll /= 10000000;
	ll += bias_sec;
	return static_cast<int>(ll);
}
//----------------------------------------------------------------------------
void TimeZone::Time::_time_tToFileTime(time_t t, FILETIME* pft)
{
	// Note that LONGLONG is a 64-bit value
	__int64 ll;

	ll = Int32x32To64(t, 10000000) + 116444736000000000;
	pft->dwLowDateTime = static_cast<unsigned int>(ll);
	pft->dwHighDateTime = static_cast<unsigned int>(ll >> 32);
}
//----------------------------------------------------------------------------
void TimeZone::Time::_time_tToSystemTime(time_t t, SYSTEMTIME* pst)
{
	FILETIME ft;

	_time_tToFileTime(t, &ft);
	::FileTimeToSystemTime(&ft, pst);
}
			